#include <jni.h>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <android/log.h>
#include <jni.h>
#include <jni.h>
#include <jni.h>
#include <jni.h>

char *itoa(int num, char *str, int radix) {/*索引表*/
    char index[] = "0123456789ABCDEF";
    unsigned unum;/*中间变量*/
    int i = 0, j, k;
    /*确定unum的值*/
    if (radix == 10 && num < 0)/*十进制负数*/
    {
        unum = (unsigned) -num;
        str[i++] = '-';
    } else unum = (unsigned) num;/*其他情况*/
    /*转换*/
    do {
        str[i++] = index[unum % (unsigned) radix];
        unum /= radix;
    } while (unum);
    str[i] = '\0';
    /*逆序*/
    if (str[0] == '-')
        k = 1;/*十进制负数*/
    else
        k = 0;

    for (j = k; j <= (i - 1) / 2; j++) {
        char temp;
        temp = str[j];
        str[j] = str[i - 1 + k - j];
        str[i - 1 + k - j] = temp;
    }
    return str;
}


void my_itoa(long i, char *string) {
    int power = 0, j = 0;

    j = i;
    for (power = 1; j > 10; j /= 10)
        power *= 10;

    for (; power > 0; power /= 10) {
        *string++ = '0' + i / power;
        i %= power;
    }
    *string = '\0';
    printf("%s\n", string);
}

int iRFID_Decode96bit(char *ucBarCode) {
    int i, iDatLen, iBarCodeLen;
    unsigned char ucTmpChar;
    unsigned char ucTmpStr[9];
    unsigned char ucWorkStr[15] = "00000000000000";
    // 字符串长度实际为14位字符+结束符' \0'
    union {
        unsigned char ucStr[4];
        unsigned int uiDat;
    } unWorkDat;
    iBarCodeLen = (unsigned int) (ucBarCode[0] & 0x0F);
    __android_log_print(ANDROID_LOG_DEBUG, "rfidDecode", "%d", iBarCodeLen);
    // 获取压缩前BarCode编码长度
    if (iBarCodeLen < 1 || iBarCodeLen > 14)
        return (-1);
    if (iBarCodeLen < 8) // 处理1-7字符长度的BarCode
    {
        for (i = 0; i < iBarCodeLen; ++i) {
            ucBarCode[i] = ucBarCode[i+1];
        }
        ucBarCode[iBarCodeLen]=0;
        return (iBarCodeLen);
    }
    for (i = 0; i < 4; ++i) // 将压缩码的前面(低) 4字节取出
    {
        unWorkDat.ucStr[i] = ucBarCode[i];
    }
    unWorkDat.uiDat >>= 4;
    ucWorkStr[iBarCodeLen - 1] = (unsigned char) (unWorkDat.uiDat & 0xFF);
    // 还原最后1位字符， 即校验位
    unWorkDat.uiDat >>= 8;
    for (i = 2; i >= 0; --i) // 解码最前面3位字母或数字
    {
        ucWorkStr[i] = (unsigned char) ((unWorkDat.uiDat & 0x3F) + 0x30);
        unWorkDat.uiDat >>= 6;
    }
    ucWorkStr[3] = (unsigned char) (unWorkDat.uiDat & 0x03);
    // 还原第四位数字的低2bit
    for (i = 0; i < 4; ++i) // 将压缩码的前面(高) 4字节取出
    {
        unWorkDat.ucStr[i] = ucBarCode[i + 4];
    }
    ucWorkStr[3] = (ucWorkStr[3] | ((unsigned char) (unWorkDat.uiDat & 0x03) << 2)) + 0x30;
    // 取出第4位数字的低2bit， 还原第4位数字
    unWorkDat.uiDat >>= 2;
    itoa(unWorkDat.uiDat, (char *) ucTmpStr, 10);
    //itoa(unWorkDat.uiDat, (char *) ucTmpStr);
    // 还原BarCode从第5位起除最后1位的2-9位数字
    iDatLen = strlen((char *) ucTmpStr);
    for (i = 0; i < iDatLen; ++i) {
        ucWorkStr[i + iBarCodeLen - iDatLen - 1] = ucTmpStr[i];
    }
    //"HS202205345300"

    for (i = 0; i < iBarCodeLen; ++i) // 将解码后的BarCode通过参数返回
    {
        ucBarCode[i] = ucWorkStr[i];
    }
    ucBarCode[iBarCodeLen]=0;

    return (iBarCodeLen);
}


int iRFID_Decode128bit(unsigned char *ucBarCode) {
    int i, j, iDatLen, iBarCodeLen;
    unsigned char ucTmpChar;
    unsigned char ucTmpStr[9];
    unsigned char ucWorkStr[15] = "00000000000000";
// 字符串长度实际为14位字符+结束符' \0'
    union {
        unsigned char ucStr[4];
        unsigned int uiDat;
    } unWorkDat;
    iBarCodeLen = (unsigned int) (ucBarCode[0] & 0x0F);
// 获取编码前BarCode编码长度
    if (iBarCodeLen < 1 || iBarCodeLen > 14) return (-1);
    if (iBarCodeLen < 12) // 处理1-12字符长度的BarCode
    {
        for (i = 0; i < iBarCodeLen; ++i) {
            ucBarCode[i] = ucBarCode[i + 1];
        }
        ucBarCode[iBarCodeLen] = 0;
        return (iBarCodeLen);
    }
    for (i = 0; i < 4; ++i) // 将压缩码的低4字节取出
    {
        unWorkDat.ucStr[i] = ucBarCode[i];
    }
    unWorkDat.uiDat >>= 4;
    ucWorkStr[iBarCodeLen - 1] = (unsigned char) (unWorkDat.uiDat & 0xFF);
// 还原最后1位字符， 即校验位
    unWorkDat.uiDat >>= 8;
    for (i = iBarCodeLen - 2; i >= 10; --i) // 解码第11至倒数第2个字符
    {
        ucWorkStr[i] = (unsigned char) ((unWorkDat.uiDat & 0x3F) + 0x30);
        unWorkDat.uiDat >>= 6;
    }
    for (i = 0; i < 4; ++i) // 将压缩码的中间4字节取出
    {
        unWorkDat.ucStr[i] = ucBarCode[i + 4];
    }
    for (i = 9; i >= 5; --i) // 解码第6-10个字符
    {
        ucWorkStr[i] = (unsigned char) ((unWorkDat.uiDat & 0x3F) + 0x30);
        unWorkDat.uiDat >>= 6;
    }
    for (i = 0; i < 4; ++i) // 将压缩码的高4字节取出
    {
        unWorkDat.ucStr[i] = ucBarCode[i + 8];
    }
    for (i = 4; i >= 0; --i) // 解码第1-5个字符
    {
        ucWorkStr[i] = (unsigned char) ((unWorkDat.uiDat & 0x3F) + 0x30);
        unWorkDat.uiDat >>= 6;
    }
    for (i = 0; i < iBarCodeLen; ++i) // 将解码后的BarCode通过参数返回
    {
        ucBarCode[i] = ucWorkStr[i];
    }
    ucBarCode[iBarCodeLen] = 0;
    return (iBarCodeLen);
}

int iRFID_Encode96bit(unsigned char *ucBarCode) {
    int i, iBarCodeLen;
    unsigned char ucCompressedBarCode[4], ucTmpChar;
    unsigned char *pucTmpDat;
    union {
        unsigned char ucStr[4];
        unsigned int uiDat;
    } unWorkDat;
    iBarCodeLen = strlen((char *) ucBarCode);
    __android_log_print(ANDROID_LOG_INFO, "rfid", "iBarCodeLen = %d", iBarCodeLen);
    if (iBarCodeLen < 1 || iBarCodeLen > 14) return (-1);
    if (iBarCodeLen < 8) // 处理1-7字符长度的BarCode
    {
        for (i = iBarCodeLen; i > 0; --i) {
            ucBarCode[i] = ucBarCode[i - 1];
        }
        ucBarCode[0] = (unsigned char) iBarCodeLen;
// 存放原条码长度到低4bit
        return (iBarCodeLen);
    }
    ucTmpChar = ucBarCode[iBarCodeLen - 1]; // 临时存放BarCode校验位
    ucBarCode[iBarCodeLen - 1] = 0; // 最后一位(即校验位)清零
    pucTmpDat = &ucBarCode[4]; // 处理压缩后的高4字节
    unWorkDat.uiDat = atoi((char *) pucTmpDat);// 压缩BarCode从第5位起除最后1位的2-9位数字
    unWorkDat.uiDat <<= 2;
    unWorkDat.uiDat |=
            (((unsigned int) ucBarCode[3] - 0x30) & 0x0C) >> 2; // 将Barcode的第4位数字压缩后的高2bit存入
    for (i = 0; i < 4; ++i) // 临时保存压缩后的高4字节
    {
        ucCompressedBarCode[i] = unWorkDat.ucStr[i];
    }
// 处理压缩后的低4字节
    unWorkDat.uiDat = ((unsigned int) ucBarCode[3] - 0x30)
                      & 0x03; // 压缩第4位数字压缩后的低2bit存入
    unWorkDat.uiDat = (unWorkDat.uiDat << 6)
                      | ((unsigned int) ucBarCode[0] - 0x30); // 压缩最前面3位字母或数字
    unWorkDat.uiDat = (unWorkDat.uiDat << 6) | ((unsigned int) ucBarCode[1] - 0x30);
    unWorkDat.uiDat = (unWorkDat.uiDat << 6) | ((unsigned int) ucBarCode[2] - 0x30);
    unWorkDat.uiDat = (unWorkDat.uiDat << 8) | ((unsigned int) ucTmpChar);
// 压缩BarCode最后1位字符，通常为校验码
    unWorkDat.uiDat = (unWorkDat.uiDat << 4) | (unsigned int) iBarCodeLen;
// 记录原BarCode编码长度
    for (i = 0; i < 4; ++i) // 构成输出压缩后的BarCode
    {
        ucBarCode[i] = unWorkDat.ucStr[i];
        ucBarCode[i + 4] = ucCompressedBarCode[i];
    }
    return (iBarCodeLen);
}


jstring str2jstring(JNIEnv *env, const char *pat) {

    //定义java String类 strClass
    jclass strClass = (env)->FindClass("java/lang/String");
    //获取String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
    jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
    //建立byte数组
    jbyteArray bytes = (env)->NewByteArray(strlen(pat));
    //将char* 转换为byte数组
    (env)->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
    // 设置String, 保存语言类型,用于byte数组转换至String时的参数
    jstring encoding = (env)->NewStringUTF("utf-8");
    //将byte数组转换为java String,并输出
    return (jstring)(env)->NewObject(strClass, ctorID, bytes, encoding);
}


extern "C"
JNIEXPORT jstring

JNICALL
Java_com_shrfid_rfidsdk_tag_RfidDecoder_iRFID_1Decode96bit(JNIEnv *env, jobject thiz,
                                                           jbyteArray data) {
    char *chars = NULL;
    jbyte *bytes;
    bytes = env->GetByteArrayElements(data, 0);
    int chars_len = env->GetArrayLength(data);
    chars = new char[chars_len + 1];
    memset(chars, 0, chars_len + 1);
    memcpy(chars, bytes, chars_len);
    chars[chars_len] = 0;
    env->ReleaseByteArrayElements(data, bytes, 0);
    int result = iRFID_Decode96bit(chars);
    jstring r = nullptr;
    if (result > 0) {
//        r = env->NewStringUTF(chars);
        r = str2jstring(env,chars);
    }
    //free(buf);
//    return result;
    return r;
}

extern "C"
JNIEXPORT jint

JNICALL
Java_com_shrfid_rfidsdk_tag_RfidDecoder_iRFID_1Decode128bit(JNIEnv *env, jobject thiz,
                                                            jbyteArray data) {
    int len = env->GetArrayLength(data);
    unsigned char *buf = new unsigned char[len];
    env->GetByteArrayRegion(data, 0, len, reinterpret_cast<jbyte *>(buf));
    int result = iRFID_Decode128bit(buf);
    if (result > 0)
        env->SetByteArrayRegion(data, 0, result, reinterpret_cast<jbyte *>(buf));
    return result;
}

extern "C"
JNIEXPORT jint

JNICALL
Java_com_shrfid_rfidsdk_tag_RfidDecoder_iRFID_1Encode96bit(JNIEnv *env, jobject thiz,
                                                           jbyteArray data) {
    int len = env->GetArrayLength(data);
    __android_log_print(ANDROID_LOG_INFO, "rfid", "len = %d", len);
    unsigned char *buf = new unsigned char[len + 1];
    env->GetByteArrayRegion(data, 0, len, reinterpret_cast<jbyte *>(buf));
    buf[len] = '\0';
    int result = iRFID_Encode96bit(buf);
    if (result > 0)
        env->SetByteArrayRegion(data, 0, result, reinterpret_cast<jbyte *>(buf));
    free(buf);
    return result;
}